<?php

use Core\API_Controller;
use Models\Address;
use Models\Order;
use Models\Order_item;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use Models\User;

class PayController extends API_Controller
{
	public function index($order_id)
	{
		$order = (new Order)->find($order_id);
		if (!$order) {
			return $this->notFoundResponse();
		}
		if ($order['status'] != 0) {
			return $this->validateError('name', '此订单无需支付');
		}

		if ($this->input->get('address')) {
			// 设置地址
			$address = Address::where([
				'user_id' => $this->session->authUser['id'],
				'id' => $this->input->get('address')])
				->get_one();
			if ($address) {
				$order['address_id'] = $address['id'];
				$order->update();
			}
		}

		if ($this->input->get('shipping_time')) {
			$order['shipping_time'] = $this->input->get('shipping_time');
		}
		if ($this->input->get('shipping_date')) {
			$order['shipping_date'] = $this->input->get('shipping_date');
		}
		$order->update();

		switch ($this->input->get('pay_type')) {
			case 'balance':
				$this->balance($order);
				break;
			case 'paypal':
				$this->paypal($order);
				break;
			default:
				$this->paypal($order);
				break;
		}

		$this->paypal($order);
	}

	public function balance(Order $order)
	{
		$result = $order->payed(
	    	$order,
	    	$order['total'] - $order['cut_fee'],
	    	3,
	    	0,
	    	''
	    );

		if($result === TRUE){
			$order->purchaseRecordStock($order['id']);

			redirect(WWW_URL.'/frontend/#/me/order/detail/'.$order['id']);
		}else{
			return $this->error($result['code']);
		}
	}

	public function paypal(Order $order)
	{
		$order_items = Order_item::where('order_id', $order['id'])->with(['item', 'product'])->get();
		$apiContext = new \PayPal\Rest\ApiContext(
        	new \PayPal\Auth\OAuthTokenCredential(
	            'Acob13Jk1eLhSXpbgwtVWErhkGQMXig4mztU6G8O4wKJfrb3Ktai6NNrSXO8pOAQ_pUewUDXNgDb3mYS',     // ClientID
	            'EMSVsYIZ-uN3P3uMAPQOrmKcpaMJMZu6qj4BKxrUruLfKAeDlMrzGxdlihNBsh3OQg58_Hm5VdU9wMSr'      // ClientSecret
		    )
		);
		$apiContext->setConfig([
			'mode' => 'live'
		]);

		// item
		$payer = new Payer();
		$payer->setPaymentMethod("paypal");
		// $itemList = new ItemList();
		// foreach ($order_items as $key => $value) {
		// 	$item = new Item();
		// 	$item->setName($value['product']['en_title'])
		// 		->setCurrency('GBP')
		// 		->setQuantity(intval($value['qty']))
		// 		->setPrice(round($value['total'], 2));

		// 	$itemList->addItem($item);
		// }

		// 详情
		$details = new Details();
		$details->setShipping(round($order['shipping_fee'], 2))
			->setTax(0.00)
		    ->setSubtotal(round($order['total'], 2));

		// 总计
		$total = round($order['total'] + $order['shipping_fee'], 2);
		$amount = new Amount();
		$amount->setCurrency("GBP")
		    ->setTotal($total)
		    ->setDetails($details);

		// 事务
		$transaction = new Transaction();
		$transaction->setAmount($amount)
		    // ->setItemList($itemList)
		    ->setDescription("Payment description")
		    ->setInvoiceNumber(uniqid());

		$baseUrl = WWW_URL.'/frontend/';
		$redirectUrls = new RedirectUrls();
		$redirectUrls->setReturnUrl(WWW_URL."/api/pay/paypalAgree/".$order['id'])
		    ->setCancelUrl("$baseUrl/#/order/pay/{$order['id']}?cancel=1");
		$transaction = new Transaction();
		$transaction->setAmount($amount)
		    // ->setItemList($itemList)
		    ->setDescription("Payment description")
		    ->setInvoiceNumber(uniqid());


		$payment = new Payment();
		$payment->setIntent("sale")
		    ->setPayer($payer)
		    ->setRedirectUrls($redirectUrls)
		    ->setTransactions(array($transaction));

		$request = clone $payment;

		try {
		    $payment->create($apiContext);
		} catch (Exception $ex) {
			log_message('error', "paypal申请支付链接出错".json_encode($request).', exception:'.$ex);
			echo '<pre>';
			print_r($ex);
			echo '</pre>';
    		return $this->error('吊起支付失败');
		}

		$approvalUrl = $payment->getApprovalLink();
		redirect($approvalUrl);
		// return $this->success([
		// 	'redirectUrl' => $approvalUrl
		// ]);
	}

	// paypal 用户同意支付
	public function paypalAgree($order_id)
	{
		$apiContext = new \PayPal\Rest\ApiContext(
        	new \PayPal\Auth\OAuthTokenCredential(
	            'Acob13Jk1eLhSXpbgwtVWErhkGQMXig4mztU6G8O4wKJfrb3Ktai6NNrSXO8pOAQ_pUewUDXNgDb3mYS',     // ClientID
	            'EMSVsYIZ-uN3P3uMAPQOrmKcpaMJMZu6qj4BKxrUruLfKAeDlMrzGxdlihNBsh3OQg58_Hm5VdU9wMSr'      // ClientSecret
		    )
		);

		$apiContext->setConfig([
			'mode' => 'live'
		]);

		$order = (new Order)->find($order_id);
		if (!$order) {
			show_404();
		}
		// 执行支付过程
		$paymentId = $_GET['paymentId'];
    	$payment = Payment::get($paymentId, $apiContext);

    	$execution = new PaymentExecution();
    	$execution->setPayerId($_GET['PayerID']);

    	$transaction = new Transaction();
	    $amount = new Amount();
	    $details = new Details();

	    $details->setShipping(round($order['shipping_fee'], 2))
        ->setTax(0)
        ->setSubtotal(round($order['total'], 2));

        $amount->setCurrency('GBP');
        $total = round($order['total'] + $order['shipping_fee'], 2);
	    $amount->setTotal($total);
	    $amount->setDetails($details);
	    $transaction->setAmount($amount);

	    $execution->addTransaction($transaction);

	    try {
	        $result = $payment->execute($execution, $apiContext);

	        try {
	            $payment = Payment::get($paymentId, $apiContext);
	        } catch (Exception $ex) {
	        	log_message('error', "Payment::get() error, paymentId:{$paymentId}, exception:".$ex);
	        	echo '支付失败';
	            exit(1);
	        }
	    } catch (Exception $ex) {
	    	log_message('error', "Payment::execute error, execution:".json_encode($execution).", apiContext:".json_encode($apiContext).", ex:".$ex);
	    	echo '支付失败';
	        exit(1);
	    }

	    $result = $order->payed(
	    	$order,
	    	0,
	    	3,
	    	array_reduce($payment->getTransactions(), function($car, $item) {
	    		$car = (float) $car;
	    		$amount = $item->getAmount();
	    		return (float) $car+$amount->getTotal();
	    	}),
	    	$payment->getId()
	    );

		if($result === TRUE){
			$order->purchaseRecordStock($order_id);

			redirect(WWW_URL.'/frontend/#/me/order/detail/'.$order['id']);
		}else{
			return $this->error($result['code']);
		}

	    // 跳转回前台页面

	}
}
